/*
 * Copyright (c) 2012-2020 MIRACL UK Ltd.
 *
 * This file is part of MIRACL Core
 * (see https://github.com/miracl/core).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "arch.h"
#include "ecp_BN254.h"

namespace BN254 {

/* Curve BN254 - Pairing friendly BN curve */

/* Nogami's fast curve */

#if CHUNK==16

using namespace B256_13;

const int CURVE_Cof_I=1;
const int CURVE_B_I= 2;
const BIG CURVE_B= {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
const BIG CURVE_Order= {0xD,0x0,0x0,0x0,0xA10,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A};
const BIG CURVE_Gx= {0x12,0x0,0x0,0x0,0x1A70,0x9,0x0,0x0,0x100,0x309,0x2,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A};
const BIG CURVE_Gy= {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
const BIG CURVE_HTPC= {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

const BIG CURVE_Bnx= {0x1,0x0,0x0,0x0,0x408,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
const BIG CURVE_Cof= {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

const BIG CURVE_Pxa= {0x1B2B,0x1F,0x932,0x1C84,0x191E,0x1F86,0x262,0x1769,0x48B,0x1523,0x1B6D,0x18C3,0x7E8,0x6C6,0x1FAE,0x16C5,0x119E,0x5DA,0x684,0xC};
const BIG CURVE_Pxb= {0xCF3,0x1EAA,0x1079,0x1869,0x10D8,0x25B,0x18DE,0xD75,0xD74,0x18FA,0xA96,0x1305,0x18C5,0x553,0xCC4,0xF06,0x1A73,0x17CD,0x5AA,0xA};
const BIG CURVE_Pya= {0xB9A,0xE69,0x1E24,0x1C0,0x119F,0x4DE,0x16F8,0x1CD7,0x1D0A,0x194D,0x88,0x1319,0x966,0x870,0xE6A,0x1268,0xBAF,0x1D03,0x625,0x4};
const BIG CURVE_Pyb= {0xE9B,0x19D6,0x1B1A,0x1A35,0x18A2,0x4AB,0x1CE7,0x1FFA,0x1006,0x1D84,0x34D,0xBE7,0x56F,0x16A2,0x1A3D,0x2A4,0x1C8B,0x1873,0xECA,0x1D};
const BIG CURVE_W[2]= {{0x3,0x0,0x0,0x0,0x40,0x1,0x0,0x0,0x180,0x30C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
const BIG CURVE_SB[2][2]= {{{0x4,0x0,0x0,0x0,0x850,0x1,0x0,0x0,0x180,0x30C,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}},{{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0xA,0x0,0x0,0x0,0x9D0,0x7,0x0,0x0,0x1E00,0x1CF0,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A}}};
const BIG CURVE_WB[4]= {{0x0,0x0,0x0,0x0,0x408,0x0,0x0,0x0,0x80,0x104,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x5,0x0,0x0,0x0,0x14A8,0x2,0x0,0x0,0x700,0xE38,0x0,0x0,0x1800,0x1120,0xC4,0x0,0x0,0x0,0x0,0x0},{0x3,0x0,0x0,0x0,0xC58,0x1,0x0,0x0,0x380,0x71C,0x0,0x0,0xC00,0x890,0x62,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x0,0x0,0xC18,0x0,0x0,0x0,0x80,0x104,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
const BIG CURVE_BB[4][4]= {{{0xD,0x0,0x0,0x0,0x608,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A},{0xC,0x0,0x0,0x0,0x608,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A},{0xC,0x0,0x0,0x0,0x608,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A},{0x2,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}},{{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0xC,0x0,0x0,0x0,0x608,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A},{0xD,0x0,0x0,0x0,0x608,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A},{0xC,0x0,0x0,0x0,0x608,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A}},{{0x2,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x0,0x0,0x810,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}},{{0x2,0x0,0x0,0x0,0x408,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x2,0x0,0x0,0x0,0x1020,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0xA,0x0,0x0,0x0,0x200,0x8,0x0,0x0,0x1F80,0x1FFC,0x1,0x0,0x1800,0x1A26,0x6E8,0x0,0x0,0x412,0x8D9,0x4A},{0x2,0x0,0x0,0x0,0x408,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}};


#endif

#if CHUNK==32

using namespace B256_28;

const int CURVE_Cof_I=1;
const int CURVE_B_I= 2;
const BIG CURVE_B= {0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
const BIG CURVE_Order= {0xD,0x0,0x10A1,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2};
const BIG CURVE_Gx= {0x12,0x0,0x13A7,0x0,0x86121,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2};
const BIG CURVE_Gy= {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
const BIG CURVE_HTPC= {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

const BIG CURVE_Bnx= {0x1,0x8000000,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0};
const BIG CURVE_Cof= {0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

const BIG CURVE_Pxa= {0x803FB2B,0xEE4224C,0x8BF0D91,0x8BBB489,0xDB6A464,0x7E8C61E,0xFEB8D8C,0x519EB62,0x61A10BB,0x0};
const BIG CURVE_Pxb= {0x7D54CF3,0x8C34C1E,0x784B70D,0x746BAE3,0xA5B1F4D,0x8C5982A,0x3310AA7,0xBA73783,0x516AAF9,0x0};
const BIG CURVE_Pya= {0x1CD2B9A,0xF0E0789,0xE09BD19,0xAE6BDB,0x22329BD,0x96698C8,0x39A90E0,0x6BAF934,0x21897A0,0x0};
const BIG CURVE_Pyb= {0xB3ACE9B,0x2D1AEC6,0x9C9578A,0x6FFD73,0xD37B090,0x56F5F38,0x68F6D44,0x7C8B152,0xEBB2B0E,0x0};
const BIG CURVE_W[2]= {{0x3,0x0,0x204,0x8000000,0x6181,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0}};
const BIG CURVE_SB[2][2]= {{{0x4,0x0,0x285,0x8000000,0x6181,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0}},{{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0xA,0x0,0xE9D,0x0,0x79E1E,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2}}};
const BIG CURVE_WB[4]= {{0x0,0x8000000,0x40,0x8000000,0x2080,0x0,0x0,0x0,0x0,0x0},{0x5,0x8000000,0x54A,0x0,0x1C707,0x8000000,0x312241,0x0,0x0,0x0},{0x3,0x8000000,0x2C5,0x8000000,0xE383,0xC000000,0x189120,0x0,0x0,0x0},{0x1,0x8000000,0xC1,0x8000000,0x2080,0x0,0x0,0x0,0x0,0x0}};
const BIG CURVE_BB[4][4]= {{{0xD,0x8000000,0x1060,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2},{0xC,0x8000000,0x1060,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2},{0xC,0x8000000,0x1060,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2},{0x2,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0}},{{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0xC,0x8000000,0x1060,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2},{0xD,0x8000000,0x1060,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2},{0xC,0x8000000,0x1060,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2}},{{0x2,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x1,0x0,0x81,0x0,0x0,0x0,0x0,0x0,0x0,0x0}},{{0x2,0x8000000,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0x2,0x0,0x102,0x0,0x0,0x0,0x0,0x0,0x0,0x0},{0xA,0x0,0x1020,0x8000000,0x7FF9F,0x8000000,0x1BA344D,0x4000000,0x5236482,0x2},{0x2,0x8000000,0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x0}}};
#endif

#if CHUNK==64

using namespace B256_56;

const int CURVE_Cof_I=1;
const int CURVE_B_I= 2;
const BIG CURVE_B= {0x2L,0x0L,0x0L,0x0L,0x0L};
const BIG CURVE_Order= {0xDL,0x800000000010A1L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L};
const BIG CURVE_Gx= {0x12L,0x13A7L,0x80000000086121L,0x40000001BA344DL,0x25236482L};
const BIG CURVE_Gy= {0x1L,0x0L,0x0L,0x0L,0x0L};
const BIG CURVE_HTPC= {0x1L,0x0L,0x0L,0x0L,0x0L};

const BIG CURVE_Bnx= {0x80000000000001L,0x40L,0x0L,0x0L,0x0L};
const BIG CURVE_Cof= {0x1L,0x0L,0x0L,0x0L,0x0L};

const BIG CURVE_Pxa= {0xEE4224C803FB2BL,0x8BBB4898BF0D91L,0x7E8C61EDB6A464L,0x519EB62FEB8D8CL,0x61A10BBL};
const BIG CURVE_Pxb= {0x8C34C1E7D54CF3L,0x746BAE3784B70DL,0x8C5982AA5B1F4DL,0xBA737833310AA7L,0x516AAF9L};
const BIG CURVE_Pya= {0xF0E07891CD2B9AL,0xAE6BDBE09BD19L,0x96698C822329BDL,0x6BAF93439A90E0L,0x21897A0L};
const BIG CURVE_Pyb= {0x2D1AEC6B3ACE9BL,0x6FFD739C9578AL,0x56F5F38D37B090L,0x7C8B15268F6D44L,0xEBB2B0EL};
const BIG CURVE_W[2]= {{0x3L,0x80000000000204L,0x6181L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L}};
const BIG CURVE_SB[2][2]= {{{0x4L,0x80000000000285L,0x6181L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L}},{{0x1L,0x81L,0x0L,0x0L,0x0L},{0xAL,0xE9DL,0x80000000079E1EL,0x40000001BA344DL,0x25236482L}}};
const BIG CURVE_WB[4]= {{0x80000000000000L,0x80000000000040L,0x2080L,0x0L,0x0L},{0x80000000000005L,0x54AL,0x8000000001C707L,0x312241L,0x0L},{0x80000000000003L,0x800000000002C5L,0xC000000000E383L,0x189120L,0x0L},{0x80000000000001L,0x800000000000C1L,0x2080L,0x0L,0x0L}};
const BIG CURVE_BB[4][4]= {{{0x8000000000000DL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x2L,0x81L,0x0L,0x0L,0x0L}},{{0x1L,0x81L,0x0L,0x0L,0x0L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000DL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x8000000000000CL,0x80000000001060L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L}},{{0x2L,0x81L,0x0L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L},{0x1L,0x81L,0x0L,0x0L,0x0L}},{{0x80000000000002L,0x40L,0x0L,0x0L,0x0L},{0x2L,0x102L,0x0L,0x0L,0x0L},{0xAL,0x80000000001020L,0x8000000007FF9FL,0x40000001BA344DL,0x25236482L},{0x80000000000002L,0x40L,0x0L,0x0L,0x0L}}};


#endif

}
